import customtkinter as ctk
import tkinter.messagebox as messagebox
import tkinter.filedialog as filedialog
from collections import deque
import json
import random

ctk.set_appearance_mode("light")  # 可选: "light" 或 "dark"
ctk.set_default_color_theme("blue")  # 主题颜色

class Task:
    def __init__(self, title, description, priority, timeslice):
        self.title = title
        self.description = description
        self.priority = priority
        self.timeslice = timeslice
        self.remaining_time = 0
        self.taskcode = 0

    def to_dict(self):
        return {"title": self.title, "description": self.description, "priority": self.priority}

    @staticmethod
    def from_dict(data):
        return Task(data["title"], data["description"], data["priority"])

    def __str__(self):
        return f"[{self.title}] {self.description[:10]}... | 优先级: {self.priority} | 时间片: {self.timeslice}s | 任务码: {self.taskcode:04d}"


class SchedulerApp:
    def __init__(self, root):
        self.root = root
        self.root.title("任务调度器")

        self.task_queue = deque()
        self.running_task = None
        self.update_interval = 1000
        self.timer = None
        self.is_running = True
        self.completed_tasks = []

        self.create_widgets()
        self.create_completed_listbox()

        self.start_scheduler()

    def create_widgets(self):
        # 新建任务区域


        
        ctk.CTkLabel(self.root, text="任务标题:").grid(row=0, column=0, padx=10, pady=5, sticky="w")
        self.title_entry = ctk.CTkEntry(self.root, width=200)
        self.title_entry.grid(row=0, column=1, padx=10, pady=5)

        ctk.CTkLabel(self.root, text="任务简介:").grid(row=1, column=0, padx=10, pady=5, sticky="w")
        self.desc_entry = ctk.CTkEntry(self.root, width=200)
        self.desc_entry.insert(0, "-")
        self.desc_entry.grid(row=1, column=1, padx=10, pady=5)

        ctk.CTkLabel(self.root, text="优先级 (0为最高):").grid(row=2, column=0, padx=10, pady=5, sticky="w")
        self.priority_entry = ctk.CTkEntry(self.root, width=200)
        self.priority_entry.grid(row=2, column=1, padx=10, pady=5)

        ctk.CTkLabel(self.root, text="时间片大小 (秒):").grid(row=3, column=0, padx=10, pady=5, sticky="w")
        self.slice_entry = ctk.CTkEntry(self.root, width=200)
        self.slice_entry.insert(0, "600")
        self.slice_entry.grid(row=3, column=1, padx=10, pady=5)

        self.add_button = ctk.CTkButton(self.root, text="添加任务", command=self.add_task)
        self.add_button.grid(row=3, column=2, padx=10, pady=5)

        ctk.CTkLabel(self.root, text="任务码:").grid(row=5, column=0, padx=10, pady=5, sticky="w")
        self.complete_taskcode = ctk.CTkEntry(self.root, width=200)
        self.complete_taskcode.grid(row=5, column=1, padx=10, pady=5)

        self.complete_button = ctk.CTkButton(self.root, text="标记为完成", command=self.mark_complete)
        self.complete_button.grid(row=5, column=2, padx=10, pady=5)

        self.pause_button = ctk.CTkButton(self.root, text="暂停", command=self.pause_scheduler)
        self.pause_button.grid(row=6, column=0, padx=10, pady=5)

        self.resume_button = ctk.CTkButton(self.root, text="继续", command=self.resume_scheduler)
        self.resume_button.grid(row=6, column=1, padx=10, pady=5)

        self.task_listbox = ctk.CTkTextbox(self.root, width=400, height=150, wrap="none")
        self.task_listbox.grid(row=10, column=0, columnspan=3, padx=10, pady=10)

        self.progress_bar = ctk.CTkProgressBar(self.root, orientation="horizontal", width=300)
        self.progress_bar.grid(row=11, column=0, columnspan=3, pady=5)

    def create_completed_listbox(self):
        ctk.CTkLabel(self.root, text="已完成任务:").grid(row=0, column=3, columnspan=2, padx=10, pady=5)

        self.completed_listbox = ctk.CTkTextbox(self.root, width=300, height=200)
        self.completed_listbox.grid(row=1, column=3, rowspan=10, padx=10, pady=5)

        self.completed_listbox.bind("<ButtonRelease-1>", self.readd_task_from_completed)

    def add_to_completed(self, task):
        self.completed_tasks.append(task)
        self.update_completed_listbox()

    def update_completed_listbox(self):
        self.completed_listbox.delete("0.0", "end")
        for task in self.completed_tasks:
            self.completed_listbox.insert("end", str(task) + "\n")

    def readd_task_from_completed(self, event):
        index = self.completed_listbox.index("current")
        if not index:
            return

        line = int(index.split('.')[0]) - 1
        if 0 <= line < len(self.completed_tasks):
            task = self.completed_tasks[line]
            task.remaining_time = task.timeslice
            self.task_queue.append(task)
            self.task_queue = deque(sorted(self.task_queue, key=lambda t: t.priority))
            self.completed_tasks.pop(line)
            self.update_completed_listbox()
            self.update_task_listbox()

    def add_task(self):
        title = self.title_entry.get()
        desc = self.desc_entry.get()
        priority_str = self.priority_entry.get()
        time_slice = self.slice_entry.get()

        if not title or not desc or not priority_str.isdigit() or not time_slice.isdigit():
            messagebox.showwarning("输入错误", "请填写完整信息，优先级为数字,时间片大小为数字")
            return

        priority = int(priority_str)
        timeslice = int(time_slice)
        task = Task(title, desc, priority, timeslice)
        task.remaining_time = timeslice

        existing_codes = {taski.taskcode for taski in self.task_queue if taski.taskcode != 0}
        while True:
            new_code = random.randint(0, 9999)
            if new_code not in existing_codes:
                task.taskcode = new_code
                break

        self.task_queue.append(task)
        self.task_queue = deque(sorted(self.task_queue, key=lambda t: t.priority))
        self.update_task_listbox()

    def start_scheduler(self):
        self.is_running = True
        self.schedule_next()

    def schedule_next(self):
        if not self.is_running:
            return

        if self.running_task:
            if self.running_task.remaining_time > 0:
                self.running_task.remaining_time -= 1
                self.root.after(self.update_interval, self.schedule_next)
                self.update_task_listbox()
                return

        if self.task_queue:
            overtask = self.running_task
            self.running_task = self.task_queue.popleft()
            self.running_task.remaining_time = self.running_task.timeslice
            self.task_queue.append(overtask)
            self.task_queue = deque(sorted((t for t in self.task_queue if t is not None), key=lambda t: t.priority))

        else:
            self.running_task = None

        self.update_task_listbox()
        self.root.after(self.update_interval, self.schedule_next)

    def pause_scheduler(self):
        self.is_running = False

    def resume_scheduler(self):
        self.is_running = True
        self.schedule_next()

    def mark_complete(self):
        taskcoden = self.complete_taskcode.get()
        if not taskcoden.isdigit():
            messagebox.showwarning("输入错误", "请输入合法的任务码")
            return

        taskcoden = int(taskcoden)

        if self.running_task and self.running_task.taskcode == taskcoden:
            self.add_to_completed(self.running_task)
            self.running_task = None
            return

        new_queue = deque()
        for task in self.task_queue:
            if task.taskcode != taskcoden:
                new_queue.append(task)
        self.task_queue = new_queue
        self.task_queue = deque(sorted((t for t in self.task_queue if t is not None), key=lambda t: t.priority))
        self.update_task_listbox()

    def update_task_listbox(self):
        self.task_listbox.delete("0.0", "end")

        if self.running_task:
            remaining = self.running_task.remaining_time
            self.task_listbox.insert("end", f"▶ 正在运行: {self.running_task} | 剩余时间: {remaining} 秒\n")
            self.progress_bar.set(remaining / self.running_task.timeslice if self.running_task.timeslice > 0 else 0)
        else:
            self.task_listbox.insert("end", "▶ 正在运行: 无任务\n")

        self.task_listbox.insert("end", "------------------------\n")
        self.task_listbox.insert("end", "等待中的任务:\n")

        for task in self.task_queue:
            self.task_listbox.insert("end", str(task) + "\n")


if __name__ == "__main__":
    root = ctk.CTk()
    app = SchedulerApp(root)
    root.mainloop()